package com.bert.generator.base.abs;

import com.bert.generator.base.GeneratorConfig;
import com.bert.generator.base.JavaPathConfig;
import com.bert.generator.base.db.DBInfo;
import com.bert.generator.base.db.ParseDBUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;

/**
 * 生产代码文件的抽象类
 * 抽取通用方法
 * 针对生成java以及web端代码提供不同的抽象类由子类实现
 */
public abstract class AbstractGenerateCode {

    protected final List<DBInfo> dbInfos;
    protected final GeneratorConfig generatorConfig;
    protected final JavaPathConfig pathConfig;

    public AbstractGenerateCode(GeneratorConfig generatorConfig) {
        this.generatorConfig = generatorConfig;
        this.pathConfig = new JavaPathConfig();
        this.dbInfos = new ParseDBUtil(generatorConfig).parseDBs();
    }

    /**
     * 生成代码操作
     */
    public void generate() {
        doGenerator();
    }

    /**
     * 实际生成代码的操作
     */
    protected abstract void doGenerator();

    /**
     * 创建并向文件中写入内容
     *
     * @param filePath
     * @param content
     */
    protected void createFile(String filePath, StringBuilder content) {
        createDictionary(filePath);
        Path path = Paths.get(filePath);
        try (BufferedWriter writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8)) {
            writer.write(content.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建并向模板中写入内容
     *
     * @param filePath     "src/main/resources/templates/Code/Student.java"
     * @param templatePath "/templates/Java/Entity.ftl"
     * @param objectMap    模板数据
     */
    protected void templateProcess(String filePath, String templatePath, Map<String, Object> objectMap) {
        if (new File(templatePath).exists()) {
            System.out.println("模板文件不存在: " + templatePath);
            return;
        }
        createDictionary(filePath);
        // 生成目标代码文件
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);
        configuration.setDefaultEncoding(StandardCharsets.UTF_8.name());
        configuration.setClassForTemplateLoading(AbstractGenerateCode.class, "/");
        try (FileOutputStream fileOutputStream = new FileOutputStream(filePath)) {
            Template template = configuration.getTemplate(templatePath);
            template.process(objectMap, new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8.name()));
        } catch (IOException | TemplateException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 创建目录：如果结尾是/，则表示是目录；
     * 如果结尾不是/，则认为最后一个/之后是文件名，会删除文件名
     *
     * @param filePath
     */
    protected void createDictionary(String filePath) {
        File file;
        if (!filePath.endsWith("/")) {
            //说明是文件，则将最后面的文件名称删除后，再创建文件名前的目录
            file = new File(filePath.substring(0, filePath.lastIndexOf("/")));
        } else {
            //参数中已经是目录
            file = new File(filePath);
        }
        if (!file.exists()) {
            file.mkdirs();
        }
    }


}
